#pragma once

#include <functional>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>

#include "noncopyable.h"
#include "Timestampp.h"
#include "CurrentThread.h"

class Channel;
class Poller;

//时间循环类 主要包含两大模块 Channel Poller(epoll的抽象)
class EventLoop : noncopyable
{
public:
    using Functor = std::function<void()>;
    EventLoop();
    ~EventLoop();

    void loop();  //开启事件循环
    void quit();  //退出事件循环

    Timestampp pollReturnTime() const { return pollReturnTime_; }

    void runInloop(Functor cb);    //在当前loop中执行cb
    void queueInloop(Functor cb);  //把cb放入队列中，并唤醒loop所在的线程，执行cb
    
    void wakeup();  //唤醒loop所在的线程

    //eventloop的方法->poller的方法，与Poller交互的接口
    void updateChannel(Channel* channel);
    void removeChannel(Channel* channel);
    bool hasChannel(Channel* channel);

    //判断eventloop对象，是否在自己的线程里面
    bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }

private:
    void handleRead();          //处理wake up
    void doPendingFunctors();   //执行回调

    using ChannelList = std::vector<Channel*>;

    std::atomic_bool looping_;  //原子操作，通过cas实现
    std::atomic_bool quit_;
    const pid_t threadId_;      //记录当前loop所在线程的id
    Timestampp pollReturnTime_; //poller返回发生事件的channels的时间点
    std::unique_ptr<Poller> poller_;

    int wakeupFd_;  //当mainloop获取一个新用户的channel，通过轮询算法选择一个subloop，唤醒subloop处理channel
    std::unique_ptr<Channel> wakeupChannel_;

    ChannelList activeChannels_;
    // Channel *currentActiveChannel_;

    std::atomic_bool callingPendingFunctors_; //标识当前loop是否有需要执行的回调操作
    std::vector<Functor> pendingFunctors_; //存储loop需要执行的所有的回调操作
    std::mutex mutex_; //互斥锁，用来保护上面的vector容器的线程安全操作
};